﻿#coding=utf-8

import random
import time 
#from Ui import *

"""
class CoolDownSet:
    
    
    abilities = []
    
    def pa_action(self, time = 1):
        
        for ability in self.abilities:
            ability.cur_time += time
            
        abilities = []
        for ability in self.abilities:
            if ability.cur_time < ability.cd_wait:
                abilities.append(ability)
                
        self.abilities = abilities
    
    def add(self, ability):
        ability.cur_time = 0
        self.abilities.append(ability)
"""

class Damage:
    g = None
    name = ""
    
    damage = 0
    mdamage = 0

    rigid_damage = 0
    rigid_mdamage = 0
    
    source = None
    
    def __init__(self, g, name, damage, mdamage, rigid_damage, rigid_mdamage, source):
        self.g = g
        self.name = name
        self.damage = damage
        self.mdamage = mdamage
        self.rigid_damage = rigid_damage
        self.rigid_mdamage = rigid_mdamage
        self.source = source
    
    
class AbilityBase(Damage):
    """description of class"""

    #g = None

    #name = ""

    cost_hp = 0
    cost_mp = 0

    #damage = 0
    #mdamage = 0

    #rigid_damage = 0
    #rigid_mdamage = 0

    before_wait = 0
    doing_wait = 0
    after_wait = 0
    cd_wait = 0

    cur_time = 0
    #max_time = 0

    targets = []
    #source = None
    
    texts = None
    
    STAT_READY = 0
    STAT_SPELL = 1
    STAT_CD = 2 
    status = STAT_READY
    
    TARGET_NONE = 0
    TARGET_UNIT = 1
    TARGET_GROUP = 2
    
    target_type = TARGET_NONE
    

    def __init__(self, g, source, name, cost_hp, cost_mp, damage, mdamage, rigid_damage, rigid_mdamage, before_wait, doing_wait, after_wait, cd_wait, texts):
        Damage.__init__(self, g, name, damage, mdamage, rigid_damage, rigid_mdamage, None)
        #self.g = g
        #self.source = source

        self.name = name

        self.cost_hp = cost_hp
        self.cost_mp = cost_mp

        #self.damage = damage
        #self.mdamage = mdamage

        #self.rigid_damage = rigid_damage
        #self.rigid_mdamage = rigid_mdamage

        self.before_wait = before_wait
        self.doing_wait = doing_wait
        self.after_wait = after_wait
        self.cd_wait = cd_wait

        self.cur_time = 0
        #self.max_time = self.before_wait + self.doing_wait + self.after_wait
        
        self.texts = texts

    def __str__(self):
        return self.name

    #def set(self, source, name, cost_hp, cost_mp, damage, mdamage, rigid_damage, rigid_mdamage, before_wait, doing_wait, after_wait, cd_wait, strings):
        
        

    def pa_action(self, time = 1):
        #can_damage = (self.damage + self.rigid_damage) > 0
        #can_mdamage = (self.mdamage + self.rigid_mdamage) > 0

        if self.status == self.STAT_READY:
            return
        
        if self.cur_time < self.before_wait:
            self.pa_before()

        elif self.cur_time < self.before_wait + self.doing_wait:
            self.pa_doing()

        elif self.cur_time < self.before_wait + self.doing_wait + self.after_wait:
            self.pa_after()

        elif self.cur_time < self.before_wait + self.doing_wait + self.after_wait + self.cd_wait:
            if self.status == self.STAT_SPELL:
                self.status = self.STAT_CD
                self.source.on_stop_ability()
        else:
            self.status = self.STAT_READY

        self.cur_time += time

    def pa_before(self):
        pass

    def pa_doing(self):
        pass

    def pa_after(self):
        pass

    def start(self, targets):
        self.status = self.STAT_SPELL
        self.cur_time = 0
        self.targets = targets
        
    def stop(self):
        if self.status == self.STAT_SPELL:
            self.status = self.STAT_CD
            self.cur_time = self.before_wait + self.doing_wait + self.after_wait
        
    def can_cast(self):
        return not ((self.status != self.STAT_READY) or (self.source.hp < self.cost_hp) or (self.source.mp < self.cost_mp))



class NormalAttact(AbilityBase):

    def __init__(self, g, source, name, damage, before_wait, after_wait, cd_wait, texts):
        AbilityBase.__init__(self, g, source, name, 0, 0, damage, 0, 0, 0, before_wait, 1, after_wait, cd_wait, texts)

    def pa_doing(self):
        damage = self.damage
        damage += int(random.uniform(-0.1 * self.damage, 0.1 * self.damage))
        
        if damage < 1:
            damage = 1

        self.g.ui.output(self.texts.get_text(1) % (self.source.name, self.targets[0].name))
        self.g.ui.output("\n")
        #time.sleep(self.g.time_delay)
        last_damage = self.targets[0].on_damage(self, damage, self.rigid_damage)
        self.targets[0].on_last_damage(self, last_damage)
        
    def pa_before(self):
        if self.cur_time == 0:
            self.texts.set_random_index()
            #self.g.ui.output("%d/%d\n" % (self.string_index, len(self.strings)))
            self.g.ui.output(self.texts.get_text(0) % (self.source.name))
            self.g.ui.output(" \n\n")
            time.sleep(self.g.time_delay)
        


class NormalMagic(AbilityBase):

    def __init__(self, g, source, name, cost_mp, mdamage, before_wait, after_wait, cd_wait, texts):
        AbilityBase.__init__(self, g, source, name, 0, cost_mp, 0, mdamage, 0, 0, before_wait, 1, after_wait, cd_wait, texts)

    def pa_doing(self):
        mdamage = self.mdamage
        mdamage += int(random.uniform(-0.1 * self.mdamage, 0.1 * self.mdamage))
        
        if mdamage < 1:
            mdamage = 1

        self.g.ui.output(self.texts.get_text(1) % (self.source.name, self.targets[0].name))
        self.g.ui.output("\n")
        #time.sleep(self.g.time_delay)
        last_damage = self.targets[0].on_mdamage(self, mdamage, self.rigid_mdamage)
        self.targets[0].on_last_damage(self, last_damage)
        
    def pa_before(self):
        if self.cur_time == 0:
            self.texts.set_random_index()
            #self.g.ui.output("%d/%d\n" % (self.string_index, len(self.strings)))
            self.g.ui.output(self.texts.get_text(0) % (self.source.name))
            self.g.ui.output("\n\n")
            time.sleep(self.g.time_delay)
        

class BuffBase(Damage):
    """buff"""
    
    #g = None
    
    #name = ""
    #duration =  0
    cur_time = 0
    target = None
    #source = None
    
    texts = None
    
    can_stack = False
    
    is_activing = False
    
    
    
    
    def __init__(self, g, name, source, duration, can_stack, texts):
        Damage.__init__(self, g, name, 0, 0, 0, 0, source)
        #self.g = g
        #self.name = name
        #self.source = source
        self.duration = duration
        self.can_stack = can_stack
        self.texts = texts
        
    def start(self, target):
        self.target = target
        self.cur_time = 0
        self.on_start()
        self.is_activing = True
    
    def stop(self):
        self.on_stop()
        self.is_activing = False
        
    def on_start(self):
        pass
    
    def on_stop(self):
        pass
    
    def pa_action(self):
        pass


class DamageBuff(BuffBase):
    
    def __init__(self, g, name, source, duration, damage, rigid_damage, mdamage, rigid_mdamage, can_stack, texts):
        BuffBase.__init__(self, g, name, source, duration, can_stack, texts)
        
        self.damage = damage
        self.rigid_damage = rigid_damage
        
        self.mdamage = mdamage
        self.rigid_mdamage = rigid_mdamage
        
    def on_start(self):
        self.texts.set_random_index()
        self.g.ui.output(self.texts.get_text(0) % self.target)
        self.g.ui.output("\n")
        self.g.ui.output("\n")
        time.sleep(self.g.time_delay)
    
    def on_stop(self):
        self.g.ui.output(self.texts.get_text(2) % self.target)
        self.g.ui.output("\n")
        self.g.ui.output("\n")
        time.sleep(self.g.time_delay)
    
    def pa_action(self, time = 1):
        if not self.is_activing:
            return
        
        if self.cur_time < self.duration:
            self.g.ui.output(self.texts.get_text(1) % self.target)
            self.g.ui.output("\n")
            #time.sleep(self.g.time_delay)
            can_damage = (self.damage + self.rigid_damage) > 0
            can_mdamage = (self.mdamage + self.rigid_mdamage) > 0
            
            damage = self.damage
            damage += int(random.uniform(-0.1 * self.damage, 0.1 * self.damage))
            
            mdamage = self.mdamage + self.rigid_mdamage
            mdamage += int(random.uniform(-0.1 * self.mdamage, 0.1 * self.mdamage))
            
            last_damage = 0
            
            if can_damage:
                last_damage += self.target.on_damage(self, damage, self.rigid_damage)
                
            if can_mdamage:
                last_damage += self.target.on_mdamage(self, mdamage, self.rigid_mdamage)
                
            if can_damage or can_mdamage:
                self.target.on_last_damage(self, last_damage)
            
        else:
            self.on_stop()
            self.is_activing = False
        
        self.cur_time += time
        


if __name__ == "__main__":
    print("Ability")